// Town 2: Level Raiser
// t2Raiser.txt
// This is the town script for the Level Raiser in the HLPM.
//
// The Level Raiser is the core of the HLPM. It raises a party to whatever level
// the player requests. It also can make a god party. The states used are 10-4.
// The whole Level Raiser is fairly restrictive about movement, because I don't
// want to account for what would happen if some of these flags get set but
// others don't -- this would cause weird bugs.
//
// In order to help with the restrictions, I've added the Panic Runes so that
// the player cannot possibly get stuck. The Panic Rune uses state 15.
//
// States 16-8 are stairs.
//
// Flags used:
// 2 0 = 1 party has entered Level Raiser
// 2 1 = party's initial level
// 2 2 = 1 party has selected a level
// 2 3 = party's intended level
// 2 4 = 1 party has raised levels
// 2 5 = 1 party has received final instructions out of Level Raiser
// 250 0 = number of levels party raised in the Level Raiser

begintownscript;

variables;
// Standard vars with a few extras for the Level Raiser
short i,j,k,l,choice,which_state;
short what_num = 0;
short just_selected = 0;
string dlgstr;

body;

beginstate INIT_STATE;
	set_crime_tolerance(1);

	// Get rid of those ugly braziers. They're only there for light.
	set_terrain(26,31,0);
	set_terrain(26,21,0);
	set_terrain(25,5,0);
	
	// Prevent combat-bugging down the stairs.
	change_blocked(22,35,1);
	change_blocked(23,35,1);
	change_blocked(24,35,1);
	change_blocked(25,35,1);
	change_blocked(26,35,1);
	change_blocked(22,36,1);
	change_blocked(23,36,1);
	change_blocked(24,36,1);
	change_blocked(25,36,1);
	change_blocked(26,36,1);
	
	change_blocked(23,1,1);
	change_blocked(24,1,1);
	change_blocked(25,1,1);
	change_blocked(23,2,1);
	change_blocked(24,2,1);
	change_blocked(25,2,1);
	
	change_blocked(18,4,1);
	change_blocked(18,5,1);
	change_blocked(18,6,1);
	change_blocked(19,4,1);
	change_blocked(19,5,1);
	change_blocked(19,6,1);
	
	// Now prevent combat-bugging through the Level Raiser.
	change_blocked(22,13,1);
	change_blocked(23,13,1);
	change_blocked(24,13,1);
	change_blocked(25,13,1);
	change_blocked(26,13,1);
	
	change_blocked(22,18,1);
	change_blocked(23,18,1);
	change_blocked(24,18,1);
	change_blocked(25,18,1);
	change_blocked(26,18,1);
	
	change_blocked(22,23,1);
	change_blocked(23,23,1);
	change_blocked(24,23,1);
	change_blocked(25,23,1);
	change_blocked(26,23,1);
	
	change_blocked(22,28,1);
	change_blocked(23,28,1);
	change_blocked(24,28,1);
	change_blocked(25,28,1);
	change_blocked(26,28,1);
	
	// Re-zero the flags.
	set_flag(2,0,0);
	set_flag(2,1,0);
	set_flag(2,2,0);
	set_flag(2,3,0);
	set_flag(2,4,0);
	set_flag(2,5,0);

break;

beginstate EXIT_STATE;
break;

beginstate START_STATE;

// If the party is in combat mode and they're not near the Arena, tell them to
// cut it out.
if (is_combat())
	message_dialog("Entering combat mode outside the Arena is NOT recommended.","");

// Punish crime with instant death.
if (get_crime_level() >= 1) {
	kill_char(1000,2,0);
	message_dialog("Crimes in the HLPM are punishable by instant death, as you discover the hard way.","");
	}

break;

beginstate 10; // Entry to Level Raiser

// Figures out the party's level and sets flag (2,1) to that number. Also tells
// the player what the level is. The difference between this initial level and
// the final level at the end of the Level Raiser will determine the amount of
// money that the player gets to shop with.
	i = 0;
	if (char_ok(0))
		i = i + get_level(0);
	if (char_ok(1))
		i = i + get_level(1);
	if (char_ok(2))
		i = i + get_level(2);
	if (char_ok(3))
		i = i + get_level(3);
	i = i / party_size();
		
	clear_buffer();
	append_string("The HLPM reads your party as level ");
	append_number(i);
	get_buffer_text(dlgstr);
	print_str_color(dlgstr,3);
	
	// If the party is walking back through the Level Raiser, don't set the flag
	// again.
	if (get_flag(2,0) == 0)
		set_flag(2,1,i);
	
	// If it is a god party, don't let it in.
	if (get_flag(2,1) >= 250) {
		block_entry(1);
		message_dialog("Your party is already as high as the Level Raiser can make it. You cannot enter.","");
		end();
		}

// The rest is a one-time effect.
if (get_flag(2,0) != 0)
	end();
	
	set_flag(2,0,1);
	
	// Once they enter, they cannot back out, as this would cause weird effects,
	// so be absolutely sure they want in.
	reset_dialog();
	add_dialog_str(0,"Welcome to the Level Raiser! Once you enter, you may not leave. Are you absolutely sure you wish to use the Level Raiser right now?",0);
	add_dialog_choice(0,"No. (Back away.)");
	add_dialog_choice(1,"Yes. (Keep going.)");
	if (run_dialog(1) == 1)
		block_entry(1);
	else {
		set_terrain(20,7,422);
		set_terrain(21,7,422);
		set_terrain(22,7,422);
		set_terrain(23,7,422);
		set_terrain(24,7,422);
		set_terrain(25,7,422);
		set_terrain(26,7,422);
		set_terrain(27,7,422);
		set_terrain(28,7,422);
		set_terrain(20,8,384);
		
		message_dialog("Bear in mind that if you should at any point become trapped and need to exit the Level Raiser, there are blue panic runes that will take you entirely out of the HLPM. If you're trapped, step on a blue rune.","");
		}
break;

beginstate 11; // Level Raiser's level selecting state.
// Make this a one-time.
if (get_flag(2,2) != 0)
	end();
		
	// If we are returning from the numeric input function, skip a few steps.
	// Otherwise, tell the player to choose a level.
	if (just_selected == 0) {
	reset_dialog();
	add_dialog_str(0,"You must enter what level you want you characters to be. In the following pop-up box, enter a numeral less than 100 (ie, 10, 35, 52). If you want a god party, enter _god._",0);
	add_dialog_str(1,"(Note: your characters will gain experience until their average is this level. Character traits or number of characters in the party do not affect this.)",0);
	run_dialog(1);
	
	which_state = 11;
	set_state_continue(12); // Call numeric input function.
	}
	
	// Reset the variable.
	just_selected = 0;
	
	// If they've chosen a level not greater than their current level, send them 
	// back to the numeric input function.
	if (what_num < get_flag(2,1)) {
		message_dialog("Oops! That's not higher than your party's current level! The HLPM can't decrease your level, so you will have to enter something else.","");
		set_state_continue(12);
		}
		
	// Let them know what level they have chosen. Ask if it is correct. If not,
	// send them back to the numeric input function.
	reset_dialog();
	clear_buffer();
	append_string("You have chosen level ");
	append_number(what_num);
	append_string(".");
	get_buffer_text(dlgstr);
	add_dialog_str(0,dlgstr,0);
	if (what_num == 250)
		add_dialog_str(1,"(That's a god party.)",0);
	add_dialog_str(2,"Is that correct?",0);
	add_dialog_choice(0,"Yes.");
	add_dialog_choice(1,"No. Let's try again.");
	add_dialog_choice(2,"I changed my mind. Cancel all of this.");
	choice = run_dialog(1);
	if (choice == 2)
		set_state_continue(12);
	if (choice == 3) {
		block_entry(1);
		set_flag(2,2,0);
		end();
		}
		
	// The level is correct, so set the flag. Flag (2,3) is what level they
	// want.
	set_flag(2,3,what_num);
	
	set_flag(2,2,1); // One-time it
	
	// Warn to turn off sound or else game will slow down a LOT.
	message_dialog("Head south across the runes, and you will rise to the level you requested.","Before you do this, TURN OFF BOA'S SOUND (not the computer's sound, but BoA's sound). If you don't, the game will sit almost forever making level chimes.");
break;

beginstate 12;
	// Numeric input function. Sets variable what_num to whatever the input was.
	// Then goes to which_state, which was presumably defined in the state that
	// called this function.
	//
	// NOTE: This function uses the variable just_selected to tell whether BoA
	// is returning from the function or hasn't started it yet. Make sure
	// just_selected is 0 when you begin the state that calls this function, and
	// make sure to zero it again after this function is over.
	
	what_num = 0;
	
	get_text_response("What level?");
	check_text_response_match("1");
	if (got_text_match())
		what_num = 1;
	check_text_response_match("2");
	if (got_text_match())
		what_num = 2;
	check_text_response_match("3");
	if (got_text_match())
		what_num = 3;
	check_text_response_match("4");
	if (got_text_match())
		what_num = 4;
	check_text_response_match("5");
	if (got_text_match())
		what_num = 5;
	check_text_response_match("6");
	if (got_text_match())
		what_num = 6;
	check_text_response_match("7");
	if (got_text_match())
		what_num = 7;
	check_text_response_match("8");
	if (got_text_match())
		what_num = 8;
	check_text_response_match("9");
	if (got_text_match())
		what_num = 9;
	check_text_response_match("10");
	if (got_text_match())
		what_num = 10;
	check_text_response_match("11");
	if (got_text_match())
		what_num = 11;
	check_text_response_match("12");
	if (got_text_match())
		what_num = 12;
	check_text_response_match("13");
	if (got_text_match())
		what_num = 13;
	check_text_response_match("14");
	if (got_text_match())
		what_num = 14;
	check_text_response_match("15");
	if (got_text_match())
		what_num = 15;
	check_text_response_match("16");
	if (got_text_match())
		what_num = 16;
	check_text_response_match("17");
	if (got_text_match())
		what_num = 17;
	check_text_response_match("18");
	if (got_text_match())
		what_num = 18;
	check_text_response_match("19");
	if (got_text_match())
		what_num = 19;
	check_text_response_match("20");
	if (got_text_match())
		what_num = 20;
	check_text_response_match("21");
	if (got_text_match())
		what_num = 21;
	check_text_response_match("22");
	if (got_text_match())
		what_num = 22;
	check_text_response_match("23");
	if (got_text_match())
		what_num = 23;
	check_text_response_match("24");
	if (got_text_match())
		what_num = 24;
	check_text_response_match("25");
	if (got_text_match())
		what_num = 25;
	check_text_response_match("26");
	if (got_text_match())
		what_num = 26;
	check_text_response_match("27");
	if (got_text_match())
		what_num = 27;
	check_text_response_match("28");
	if (got_text_match())
		what_num = 28;
	check_text_response_match("29");
	if (got_text_match())
		what_num = 29;
	check_text_response_match("30");
	if (got_text_match())
		what_num = 30;
	check_text_response_match("31");
	if (got_text_match())
		what_num = 31;
	check_text_response_match("32");
	if (got_text_match())
		what_num = 32;
	check_text_response_match("33");
	if (got_text_match())
		what_num = 33;
	check_text_response_match("34");
	if (got_text_match())
		what_num = 34;
	check_text_response_match("35");
	if (got_text_match())
		what_num = 35;
	check_text_response_match("36");
	if (got_text_match())
		what_num = 36;
	check_text_response_match("37");
	if (got_text_match())
		what_num = 37;
	check_text_response_match("38");
	if (got_text_match())
		what_num = 38;
	check_text_response_match("39");
	if (got_text_match())
		what_num = 39;
	check_text_response_match("40");
	if (got_text_match())
		what_num = 40;
	check_text_response_match("41");
	if (got_text_match())
		what_num = 41;
	check_text_response_match("42");
	if (got_text_match())
		what_num = 42;
	check_text_response_match("43");
	if (got_text_match())
		what_num = 43;
	check_text_response_match("44");
	if (got_text_match())
		what_num = 44;
	check_text_response_match("45");
	if (got_text_match())
		what_num = 45;
	check_text_response_match("46");
	if (got_text_match())
		what_num = 46;
	check_text_response_match("47");
	if (got_text_match())
		what_num = 47;
	check_text_response_match("48");
	if (got_text_match())
		what_num = 48;
	check_text_response_match("49");
	if (got_text_match())
		what_num = 49;
	check_text_response_match("50");
	if (got_text_match())
		what_num = 50;
	check_text_response_match("51");
	if (got_text_match())
		what_num = 51;
	check_text_response_match("52");
	if (got_text_match())
		what_num = 52;
	check_text_response_match("53");
	if (got_text_match())
		what_num = 53;
	check_text_response_match("54");
	if (got_text_match())
		what_num = 54;
	check_text_response_match("55");
	if (got_text_match())
		what_num = 55;
	check_text_response_match("56");
	if (got_text_match())
		what_num = 56;
	check_text_response_match("57");
	if (got_text_match())
		what_num = 57;
	check_text_response_match("58");
	if (got_text_match())
		what_num = 58;
	check_text_response_match("59");
	if (got_text_match())
		what_num = 59;
	check_text_response_match("60");
	if (got_text_match())
		what_num = 60;
	check_text_response_match("61");
	if (got_text_match())
		what_num = 61;
	check_text_response_match("62");
	if (got_text_match())
		what_num = 62;
	check_text_response_match("63");
	if (got_text_match())
		what_num = 63;
	check_text_response_match("64");
	if (got_text_match())
		what_num = 64;
	check_text_response_match("65");
	if (got_text_match())
		what_num = 65;
	check_text_response_match("66");
	if (got_text_match())
		what_num = 66;
	check_text_response_match("67");
	if (got_text_match())
		what_num = 67;
	check_text_response_match("68");
	if (got_text_match())
		what_num = 68;
	check_text_response_match("69");
	if (got_text_match())
		what_num = 69;
	check_text_response_match("70");
	if (got_text_match())
		what_num = 70;
	check_text_response_match("71");
	if (got_text_match())
		what_num = 71;
	check_text_response_match("72");
	if (got_text_match())
		what_num = 72;
	check_text_response_match("73");
	if (got_text_match())
		what_num = 73;
	check_text_response_match("74");
	if (got_text_match())
		what_num = 74;
	check_text_response_match("75");
	if (got_text_match())
		what_num = 75;
	check_text_response_match("76");
	if (got_text_match())
		what_num = 76;
	check_text_response_match("77");
	if (got_text_match())
		what_num = 77;
	check_text_response_match("78");
	if (got_text_match())
		what_num = 78;
	check_text_response_match("79");
	if (got_text_match())
		what_num = 79;
	check_text_response_match("80");
	if (got_text_match())
		what_num = 80;
	check_text_response_match("81");
	if (got_text_match())
		what_num = 81;
	check_text_response_match("82");
	if (got_text_match())
		what_num = 82;
	check_text_response_match("83");
	if (got_text_match())
		what_num = 83;
	check_text_response_match("84");
	if (got_text_match())
		what_num = 84;
	check_text_response_match("85");
	if (got_text_match())
		what_num = 85;
	check_text_response_match("86");
	if (got_text_match())
		what_num = 86;
	check_text_response_match("87");
	if (got_text_match())
		what_num = 87;
	check_text_response_match("88");
	if (got_text_match())
		what_num = 88;
	check_text_response_match("89");
	if (got_text_match())
		what_num = 89;
	check_text_response_match("90");
	if (got_text_match())
		what_num = 90;
	check_text_response_match("91");
	if (got_text_match())
		what_num = 91;
	check_text_response_match("92");
	if (got_text_match())
		what_num = 92;
	check_text_response_match("93");
	if (got_text_match())
		what_num = 93;
	check_text_response_match("94");
	if (got_text_match())
		what_num = 94;
	check_text_response_match("95");
	if (got_text_match())
		what_num = 95;
	check_text_response_match("96");
	if (got_text_match())
		what_num = 96;
	check_text_response_match("97");
	if (got_text_match())
		what_num = 97;
	check_text_response_match("98");
	if (got_text_match())
		what_num = 98;
	check_text_response_match("99");
	if (got_text_match())
		what_num = 99;
	check_text_response_match("100");
	if (got_text_match())
		what_num = 100;
	check_text_response_match("god");
	if (got_text_match())
		what_num = 250;
		
	// Make sure the player actually entered something correct, and if not,
	// start over.
	if (what_num == 0)
		{message_dialog("Unfortunately, that was not an integer between 1 and 100. (Again, sample responses would include _15,_ _37,_ or _41._)","Let's try again.");
		set_state_continue(12);
		}
		
	just_selected = 1;
	set_state_continue(which_state);
break;

beginstate 13; // The actual level-raising state.
// Make this a one-time.
if (get_flag(2,4) != 0)
	end();
	
	set_flag(2,4,1);
	
	// Figure out who's in the party. The first character becomes i, the second
	// j, and the third k. If there are four, ignore this madness.
	i = 0;
	while (char_ok(i) == 0)
		{i = i + 1; }
	if (party_size() == 2)
		{if (char_ok(i + 3))
			j = i + 3;
		if (char_ok(i + 2))
			j = i + 2;
		if (char_ok(i + 1))
			j = i + 1;
		}
	if (party_size() == 3)
		{if (char_ok(i + 3) == 0)
			{j = i + 1;
			k = i + 2; }
		if (char_ok(i + 2) == 0)
			{j = i + 1;
			k = i + 3; }
		if (char_ok(i + 1) == 0)
			{j = i + 2;
			k = i + 3; }
		}
		
	// Note: this is the critical level-raising part. It raises the party up to 
	// an average level of whatever flag (2,3) is.
	if (party_size() == 1) {
		while (get_level(i) < get_flag(2,3))
			{award_party_xp(150,get_level(i) + 10); }
		}
	if (party_size() == 2) {
	while (get_level(i) + get_level(j) < get_flag(2,3) * 2)
			{award_party_xp(150,get_level(i) + 10); }
		}
	if (party_size() == 3) {
		while (get_level(i) + get_level(j) + get_level(k) < get_flag(2,3) * 3)
			{award_party_xp(150,get_level(i) + 10); }
		}
	if (party_size() == 4) {
		while (get_level(0) + get_level(1) + get_level(2) + get_level(3) < get_flag(2,3) * 4)
			{award_party_xp(150,get_level(i) + 10); }
		}
		
	// If they are not a god party, tell them to train and then end the state.
	if (get_flag(2,3) < 250) {
		message_dialog("Isn't this fun? You should probably train now.","Once you are done with that, continue heading south.");
		end();
		}
	
		// Otherwise, keep going. Give them skills, traits, spells, items,
		// abilities, and recipes. Then heal them, because when their endurance
		// rises, their health stays the same.
		message_dialog("Isn't this fun? Now let's give you some added firepower. Not that you'll need it, really, but you are supposed to be making a GOD party.","Don't worry about what happens over the next few seconds. You must die once to be made immortal.");
		i = 0;  // Remove their items.
		while (i < 4) {
			if (char_ok(i)) {
				kill_char(i,2,0);
				restore_pc(i);
				}
			i = i + 1;
			}
		i = 0; // Give them skills.
		while (i < 4)
			{if (char_ok(i)) {
				j = 0;
				while (j < 31) {
					alter_stat(i,j,50);
					j = j + 1;
					}
				}
			i = i + 1;
			}
		i = 0; // Give them spells.
		while (i < 4)
			{if (char_ok(i))
				{j = 0;
				while (j < 20) {
					change_spell_level(i,0,j,95);
					change_spell_level(i,1,j,95);
					j = j + 1;
					}
				}
			i = i + 1;
			}
		j = 450; // Give them god items.
		while (j <= 460) {
			char_give_item(1000,j);
			j = j + 1;
			}
		// Give them other god items (arrows, potions). Unfortunately, this
		// doesn't work with char_give_item, so the player will have to shuffle
		// the items. It shouldn't be too hard, though.
		i = 0;
		while (i < 4) {
			if (char_ok(i)) {
				j = 465;
				while (j >= 462) {
					k = 0;
					while (k < 100)
						{k = k + reward_give(j); }
					j = j - 1;
					}
				}
			i = i + 1;
			}
		i = 0;
		while (i < 4) {
			if (char_ok(i)) {
				k = 0;
				while (k < 20)
					{k = k + reward_give(461); }
				}
			i = i + 1;
			}
		i = 0; // Give them all beneficial traits.
		while (i < 4) {
			if (char_ok(i)) {
				j = 0;
				while (j < 10) {
					set_char_trait(i,j,1);
					j = j + 1;
					}
				}
			i = i + 1;
			}
		i = 0; // Give them special abilities.
		while (i < 4) {
			if (char_ok(i)) {
				j = 15;
				while (j < 22) {
					set_char_trait(i,j,1);
					j = j + 1;
					}
				}
			i = i + 1;
			}
		i = 0; // Give them recipes.
		while (i < 17) {
			give_recipe(i);
			i = i + 1;
			}
		i = 0; // Heal them.
		while (i < 4) {
			restore_pc(i);
			i = i + 1;
			}
		message_dialog("You are now super-powered. If you'd like to get other items, you can step on the runes in the corners of the upcoming Shopping Area to get money. The amount is unlimited, so buy whatever you like!","Despite how many levels you just gained, DON'T TRAIN. The HLPM will raise all of your skills using specials. There's some sort of error about abilities getting too high that you may run into if you train.");
		
break;

beginstate 14; // Final instructions
// Flag (250,0) is how much the party has gained in level. The HLPM uses this
// primarily for giving them money.
if (get_flag(2,5) != 0)
	end();
	
	inc_flag(250,0,get_flag(2,3) - get_flag(2,1));
	add_dialog_str(0,"Now you need some items. Fortunately, there is a shopping area near here. Continue south down the stairs and you will reach it.",0);
	add_dialog_str(1,"Once you get to the Shopping Area, step on one of the runes in a corner to get money. Buy whatever you like, but be careful with your money, because you will only get 1000 coins for every level that you gained in the Level Raiser.",0);
	if (get_flag(2,3) < 250) {
		clear_buffer();
		append_string("In other words, this time, you will get ");
		append_number(get_flag(250,0));
		append_string(" thousand coins to spend on items and spells.");
		get_buffer_text(dlgstr);
		add_dialog_str(2,dlgstr,0);
		}
	else
		add_dialog_str(2,"However, since you made a god party, the money-giving runes will make an exception and give you unlimited money. Also, the Head Merchant will sell you some other interesting items.",0);
	add_dialog_str(3,"Bear in mind that there is a very useful utility that TM has made called the Artifacts Hall that will allow you to pick up artifacts from other scenarios. You may want to use that in conjunction with these shops in order to outfit your party.",0);
	set_flag(2,5,run_dialog(1));
break;

beginstate 15; // Panic rune
// Ask if the party wants to leave. If so, send them out of the scenario
// entirely.
	reset_dialog();
	add_dialog_str(0,"Would you like to leave the HLPM entirely? (You should probably only do this if you're irrevocably stuck.)",0);
	add_dialog_choice(0,"No. Let me finish this.");
	add_dialog_choice(1,"Yes. I'm stuck. Get me out of here!");
	if (run_dialog(1) == 1)
		block_entry(1);
	else
		end_scenario(2);
break;

beginstate 16;// Stairs down to Library south
	reset_dialog();
	add_dialog_str(0,"These stairs lead to the Library near the Ability Rune. What would you like to do?",0);
	add_dialog_choice(0,"Leave.");
	add_dialog_choice(1,"Descend the stairs.");
	if (run_dialog(1) == 1)
		block_entry(1);
	else
		move_to_new_town(1,24,33);
break;

beginstate 17;// Stairs down to Library east
	reset_dialog();
	add_dialog_str(0,"These stairs lead to the Library near its northeast corner. What would you like to do?",0);
	add_dialog_choice(0,"Leave.");
	add_dialog_choice(1,"Descend the stairs.");
	if (run_dialog(1) == 1)
		block_entry(1);
	else
		move_to_new_town(1,40,5);
break;

beginstate 18;// Stairs down to Shopping Area
	reset_dialog();
	add_dialog_str(0,"These stairs lead to the Shopping Area. What would you like to do?",0);
	add_dialog_choice(0,"Leave.");
	add_dialog_choice(1,"Descend the stairs.");
	if (run_dialog(1) == 1)
		block_entry(1);
	else
		move_to_new_town(3,24,4);
break;